﻿using Bandit.Helpers;
//new
using Bandit.UI;
using Bandit.UI.Controls;
using BeanGo.DataGridDemo.Core;
using BeanGo.DataGridDemo.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace BeanGo.DataGridDemo
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : BanditWindow
    {
        /// <summary>
        /// 视图模型
        /// </summary>
        public ViewModels.MainViewModel ViewModel { get { return App.MainViewModel; } }

        public MainWindow()
        {
            InitializeComponent();

            TestConfig.LoadConfig();

            #region Window Loaded

            this.Loaded += delegate
            {
                ViewModel.OnClick = new Bandit.UI.MVVM.CommandHandler(OnClick);

                this.DataContext = ViewModel;

                //在这里连接USB
                //this.InitializeUSB();

                this.txtBarcode.Focus();

                UpdateStartButtonState();
            };

            #endregion

            #region Window KeyDown
            this.KeyDown += (sender, e) =>
            {
                if (e.Key == Key.F5 || e.Key == Key.Enter)
                {
                    this.StartTest();
                }
            };
            #endregion
        }

        #region OnClick Event

        private void OnClick(object parameter)
        {
            if (parameter != null)
            {
                switch (parameter.ToString())
                {
                    case "StartTest":
                        {
                            this.StartTest();
                        }
                        break;
                    case "StopTest":
                        {
                            this.StopTest();
                        }
                        break;
                    case "CancelLoop":
                        {
                            borderLoop.Visibility = Visibility.Collapsed;
                            ViewModel.TestConfig.IsLoopTest = false;
                            TestConfig.SaveConfig();
                        }
                        break;
                    case "TestConfig":
                        {
                            ShowWindow<Windows.FrmConfig>(this);
                        }
                        break;
                    case "Setting":
                        {
                            ShowWindow<Windows.FrmSetting>(this);
                        }
                        break;
                    case "CheckUpdate":
                        if (!App.CheckUpdate())
                        {
                            this.ShowDialog(App.GetString("NotNeedUpdatePrompt"), App.GetString("Prompt"), MessageBoxButton.OK, Bandit.UI.DialogIcon.OK);
                        }
                        break;
                    case "About":
                        {
                            Windows.FrmAbout.Show(this);
                        }
                        break;
                    default:
                        break;
                }
            }
        }

        #endregion

        #region 当设备连接或断开后更新开始测试按钮的状态
        private void UpdateStartButtonState()
        {
            ViewModel.TestInfo.EnabledStartButton = true; //RelayBoardHelper.RelayBoards.All(s => s.IsConnect) && this._Meter.IsConnected;

            if (ViewModel.TestInfo.EnabledStartButton)
            {
                ViewModel.Status.Update("Ready", MyBrushes.RichBlue);
            }
            else
            {
                ViewModel.Status.Update("Wating...", MyBrushes.RichRed);
            }
        }
        #endregion


        #region [开始测试]
        private void StartTest()
        {
            if (!ViewModel.TestInfo.EnabledStartButton)
            {
                return;
            }

            //在这里判断USB\COM等设备是否连接


            //判断是否为工程师模式，否则必须输入SN
            if (!ViewModel.EngineerMode)
            {
                string promptText = string.Empty;
                this.ThreadSafe(() =>
                {
                    promptText = this.txtBarcode.PromptText;
                }, false);
                if (string.IsNullOrWhiteSpace(ViewModel.TestInfo.Barcode) || ViewModel.TestInfo.Barcode == promptText)
                {
                    this.ShowDialog("Please input SN Barcode！", App.GetString("Prompt"), MessageBoxButton.OK, Bandit.UI.DialogIcon.Please);
                    this.ThreadSafe(() =>
                    {
                        this.txtBarcode.Focus();
                    }, false);
                    return;
                }
            }

            //测试开始，更新界面显示
            ViewModel.TestInfo.TestStart();

            //更新状态栏显示
            ViewModel.Status.Update("Testing...", MyBrushes.RichYellow);

            //显示测试中效果UI
            this.Loading.Show("Testing...");

            //在这里重置USB\COM等设备是否连接
            //RelayBoardHelper.Reset();

            Task.Factory.StartNew(() =>
            {
                //在这里执行测试功能
                Thread.Sleep(5000);

            }).ContinueWith(task =>
            {
                this.Loading.Hide();

                FinishTest(false);
            });
        }
        #endregion

        #region [停止测试]
        private void StopTest()
        {
            this.Loading.Show("Stopping...");

            this.FinishTest(true);
        }
        #endregion

        #region [完成测试]
        /// <summary>
        /// 完成测试
        /// </summary>
        /// <param name="isStoped">表示是否手动停止测试</param>
        private void FinishTest(bool isStoped)
        {
            //获取测试结果状态
            TestResultState result = isStoped ? TestResultState.Stop : true ? TestResultState.Pass : TestResultState.Fail;

            ViewModel.TestInfo.TestEnd(result);

            if (isStoped)
            {
                ViewModel.Status.Update("Test Stopped.", MyBrushes.Yellow);
            }
            else
            {
                ViewModel.Status.Update("Test Finished", MyBrushes.Green);

                WriteTestLog(result);
            }

            //在这里重置USB\COM等设备是否连接
            //RelayBoardHelper.Reset();

            this.ThreadSafe(() =>
            {
                this.txtBarcode.Focus();
                this.txtBarcode.SelectAll();
            }, false);

            this.Loading.Hide();

            #region 循环测试
            if (ViewModel.TestConfig.IsLoopTest)
            {
                Task.Factory.StartNew(() =>
                {
                    this.ThreadSafe(delegate
                    {
                        borderLoop.Visibility = Visibility.Visible;
                    });

                    for (int i = 0; i < ViewModel.TestConfig.LoopTestInterval; i++)
                    {
                        if (!ViewModel.TestConfig.IsLoopTest)
                        {
                            break;
                        }

                        this.ThreadSafe(delegate
                        {
                            this.txtLoopInfo.Text = string.Format("Test will start automatically after {0} seconds.", ViewModel.TestConfig.LoopTestInterval - i);
                        });

                        Thread.Sleep(TimeSpan.FromSeconds(1));
                    }

                    this.ThreadSafe(delegate
                    {
                        borderLoop.Visibility = Visibility.Collapsed;
                    });

                    if (ViewModel.TestConfig.IsLoopTest)
                    {
                        OnClick("StartTest");
                    }
                });
            }
            #endregion
        }
        #endregion

        #region 测试Log记录

        private void WriteTestLog(TestResultState result)
        {
            try
            {
                #region CSV Combine Define
                string collectHeader = string.Format("SerialNumber,overallResult,errCode,errString,startTime,endTime,testTime");

                string collectUpper = "UpperLimit,,,,,,";

                string collectLower = "LowerLimit,,,,,,";

                string errCode = "0";

                string errString = "OK";

                string collectData = string.Format("{0},{1},{2},{3},{4},{5},{6}",
                                         ViewModel.TestInfo.Barcode,
                                         result.ToString().ToUpper(),
                                         errCode,
                                         errString,
                                         ViewModel.TestInfo.TestTimer.StartTime.ToString("yyyy/MM/dd HH:mm:ss"),
                                         ViewModel.TestInfo.TestTimer.EndTime.ToString("yyyy/MM/dd HH:mm:ss"),
                                         ViewModel.TestInfo.TestTimer.TestTime);
                #endregion

                if (!string.IsNullOrWhiteSpace(ViewModel.TestInfo.Barcode))
                {
                    string saveDir = string.Format(@"{0}TestLog\{1}\{2}\{3}\", this.GetBaseDirectory(), ViewModel.TestConfig.Project, DateTime.Now.ToString("yyyy-MM-dd"), result.ToString().ToUpper());
                    if (!System.IO.Directory.Exists(saveDir))
                    {
                        System.IO.Directory.CreateDirectory(saveDir);
                    }

                    string logFileName = saveDir + string.Format(@"{0}_{1}_{2}_{3}_{4}.csv", result.ToString().ToUpper(), ViewModel.TestInfo.Barcode, ViewModel.TestConfig.Project, ViewModel.TestConfig.Station, DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"));

                    string csvFileName = System.IO.Path.GetDirectoryName(System.IO.Path.GetDirectoryName(saveDir)) + string.Format(@"\Combine-{0}-{1}-{2}.csv", ViewModel.TestConfig.Project, ViewModel.TestConfig.Station, DateTime.Now.ToString("yyyy-MM-dd"));

                    bool isExists = System.IO.File.Exists(csvFileName);
                    StringBuilder sbCsv = new StringBuilder();
                    if (!isExists)
                    {
                        sbCsv.AppendLine(string.Format("{0} V{1}", this.GetAssemblyName(), this.GetVersion()));
                        sbCsv.AppendLine("Project, " + ViewModel.TestConfig.Project);
                        sbCsv.AppendLine("Station, " + ViewModel.TestConfig.Station);
                        sbCsv.AppendLine(collectHeader);
                        sbCsv.AppendLine(collectUpper);
                        sbCsv.AppendLine(collectLower);
                    }
                    sbCsv.AppendLine(collectData);
                    //sbCsv.AppendLine(collectData1);
                    //sbCsv.AppendLine(collectData2);

                    using (System.IO.StreamWriter sw = new System.IO.StreamWriter(logFileName, false, Encoding.UTF8))
                    {
                        StringBuilder sbLog = new StringBuilder();
                        sbLog.AppendLine(string.Format("{0} V{1}", this.GetAssemblyName(), this.GetVersion()));
                        sbLog.AppendLine("Project, " + ViewModel.TestConfig.Project);
                        sbLog.AppendLine("Station, " + ViewModel.TestConfig.Station);
                        sbLog.AppendLine(collectHeader);
                        sbLog.AppendLine(collectUpper);
                        sbLog.AppendLine(collectLower);
                        sbLog.AppendLine(collectData);
                        //sbLog.AppendLine(collectData1);
                        //sbLog.AppendLine(collectData2);
                        sw.Write(sbLog.ToString());
                        sw.Close();
                    }

                    using (System.IO.StreamWriter sw = new System.IO.StreamWriter(csvFileName, true, Encoding.UTF8))
                    {
                        sw.Write(sbCsv.ToString());
                        sw.Close();
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.Error(ex, "WriteTestLog");
            }
        }

        #endregion
    }
}
